//
//  LiaisonBaseLite.m
//  FMS
//
//  Created by Steven on 10/20/13.
//  Copyright (c) 2013 QGSVN. All rights reserved.
//

#import "LiaisonBaseLite.h"

@implementation LiaisonBaseLite

+ (NSString*) docType {
    return kLiaisonDocType;
}

- (instancetype) initInDatabase:(CBLDatabase *)database withTitle:(NSString *)title
{
    self = [super initInDatabase:database withTitle: title];
    
    return self;
}

// Returns a query for all the lists in a database.
+ (NSMutableArray *) queryListsInDatabase: (CBLDatabase*)db {
    CBLView* view = [db viewNamed: @"listsLiaison"];
    if (!view.mapBlock) {
        // Register the map function, the first time we access the view:
        [view setMapBlock: MAPBLOCK({
            if ([doc[@"Table"] isEqualToString:kLiaisonDocType])
                emit(doc, nil);
        }) reduceBlock: nil version: @"1"]; // bump version any time you change the MAPBLOCK body!
    }
    CBLQuery *query = [view query];
    NSMutableArray *array = [NSMutableArray arrayWithCapacity:1];
    for (CBLQueryRow *row in query.rows) {
        if ([row.document.properties valueForKey:@"personInCharge"] != nil && ![[row.document.properties valueForKey:@"personInCharge"] isEqualToString:@""]
            && [row.document.properties valueForKey:@"email"] != nil
            && ![[row.document.properties valueForKey:@"email"] isEqualToString:@""])
            [array addObject:[row.document.properties mutableCopy]];
    }
    return array;
}

// Returns a filter liaison by type contract type in a database.
+ (NSMutableArray *) filterLiaisonByContactType:(NSString *) contractType inDatabase: (CBLDatabase*)db {
    CBLView* view = [db viewNamed: @"filterLiaisonByContactType"];
    if (!view.mapBlock) {
        // Register the map function, the first time we access the view:
        [view setMapBlock: MAPBLOCK({
            if ([doc[@"Table"] isEqualToString:kLiaisonDocType] && doc[@"typeLiaison"])
                emit(doc[@"typeLiaison"], nil);
        }) reduceBlock: nil version: @"1"]; // bump version any time you change the MAPBLOCK body!
    }
    CBLQuery *query = [view query];
    query.keys = @[contractType];
    NSMutableArray *array = [NSMutableArray arrayWithCapacity:1];
    for (CBLQueryRow *row in query.rows) {
        if ([row.document.properties valueForKey:@"personInCharge"] != nil && ![[row.document.properties valueForKey:@"personInCharge"] isEqualToString:@""]
             && [row.document.properties valueForKey:@"email"] != nil
             && ![[row.document.properties valueForKey:@"email"] isEqualToString:@""])
            [array addObject:[row.document.properties mutableCopy]];
    }
    return array;
}

// Returns search liaison by key in a database.
+ (NSMutableArray *) searchLiaisonByKey:(NSString *)keySearch InDatabase: (CBLDatabase*)db {
    CBLView* view = [db viewNamed: @"searchLiaison"];
    if (!view.mapBlock) {
        // Register the map function, the first time we access the view:
        [view setMapBlock: MAPBLOCK({
            if ([doc[@"Table"] isEqualToString:kLiaisonDocType])
                emit(doc, nil);
        }) reduceBlock: nil version: @"1"]; // bump version any time you change the MAPBLOCK body!
    }
    CBLQuery *query = [view query];
    NSMutableArray *array = [NSMutableArray arrayWithCapacity:1];
    for (CBLQueryRow *row in query.rows) {
        if (([row.document.properties valueForKey:@"personInCharge"] != nil && [[row.document.properties valueForKey:@"personInCharge"] rangeOfString:keySearch options:NSCaseInsensitiveSearch].location != NSNotFound)
            ||([row.document.properties valueForKey:@"email"] != nil && [[row.document.properties valueForKey:@"email"] rangeOfString:keySearch options:NSCaseInsensitiveSearch].location != NSNotFound)
            ||([row.document.properties valueForKey:@"contactNumber"] != nil && [[row.document.properties valueForKey:@"contactNumber"] rangeOfString:keySearch options:NSCaseInsensitiveSearch].location != NSNotFound)) {
            [array addObject:[row.document.properties mutableCopy]];
        }
    }
    
    return array;
}

// Returns a query for all the lists in a database.
+ (NSMutableArray *) queryLiaisonFrom:(int)indexFrom numberPage:(int)count {
    NSMutableArray *array = [LiaisonBaseLite queryListsInDatabase:[CouchBaseLiteLib sharedCouchBaseLite].database];
    NSMutableArray *arrayResult = [NSMutableArray arrayWithCapacity:1];
    for (int i = indexFrom; i < indexFrom + count &&  i < [array count]; i++) {
        [arrayResult addObject:[array objectAtIndex:i]];
    }
    return arrayResult;
}

// Returns a filter liaison by type contract type in a database.
+ (NSMutableArray *) filterLiaisonByContactType:(NSString *) contractType from:(int)indexFrom  numberPage:(int)count {
    
    NSMutableArray *array = [LiaisonBaseLite filterLiaisonByContactType:contractType inDatabase:[CouchBaseLiteLib sharedCouchBaseLite].database];
    NSMutableArray *arrayResult = [NSMutableArray arrayWithCapacity:1];
    for (int i = indexFrom;i < indexFrom + count &&  i < [array count]; i++) {
        [arrayResult addObject:[array objectAtIndex:i]];
    }
    return arrayResult;
}

// Returns search liaison by key in a database.
+ (NSMutableArray *) searchLiaisonByKey:(NSString *)keySearch  from:(int)indexFrom  numberPage:(int)count {
    NSMutableArray *array = [LiaisonBaseLite searchLiaisonByKey:keySearch InDatabase:[CouchBaseLiteLib sharedCouchBaseLite].database];
    NSMutableArray *arrayResult = [NSMutableArray arrayWithCapacity:1];
    for (int i = indexFrom;i < indexFrom + count &&  i < [array count]; i++){
        [arrayResult addObject:[array objectAtIndex:i]];
    }
    return arrayResult;
}

+ (NSMutableDictionary *)getLiaisonByEmail:(NSString *)emailAddress{
     NSMutableArray *array = [LiaisonBaseLite searchLiaisonByKey:emailAddress InDatabase:[CouchBaseLiteLib sharedCouchBaseLite].database];
    for (NSMutableDictionary *liaison in array) {
        if ([[liaison objectForKey:@"email"] isEqualToString:emailAddress])
            return liaison;
    }
    return nil;
}

// Returns a query for all liaison + user the lists in a database.
+ (NSMutableArray *) queryNewLiaisonFrom:(int)indexFrom numberPage:(int)count {
    CBLView* view = [[CouchBaseLiteLib sharedCouchBaseLite].database viewNamed: @"listsNewContact"];
    if (!view.mapBlock) {
        // Register the map function, the first time we access the view:
        [view setMapBlock: MAPBLOCK({
            if (([doc[@"Table"] isEqualToString:kLiaisonDocType] && doc[@"personInCharge"] && ![doc[@"personInCharge"] isEqualToString:@""])|| ([doc[@"Table"] isEqualToString:kUserDocType] && [[doc objectForKey:@"status"] intValue] == 1))
                emit(doc, nil);
        }) reduceBlock: nil version: @"1"]; // bump version any time you change the MAPBLOCK body!
    }
    CBLQuery *query = [view query];
    NSMutableArray *array = [NSMutableArray arrayWithCapacity:1];
    for (CBLQueryRow *row in query.rows) {
        
        //only view by user create
        if ([[row.document propertyForKey:@"Table"] isEqualToString:kUserDocType] || ([[row.document propertyForKey:@"Table"] isEqualToString:kLiaisonDocType] && [row.document propertyForKey:@"userId"] && [[row.document propertyForKey:@"userId"] isEqualToString:[[NSUserDefaults standardUserDefaults] objectForKey:ACCOUNT_ID]])) {
            [array addObject:[row.document.properties mutableCopy]];
        }
    }
    [array sortUsingComparator:^(NSMutableDictionary *obj1, NSMutableDictionary *obj2){
        NSString *name1;
        if ([[obj1 objectForKey:@"Table"] isEqualToString:kUserDocType])
            name1 = [obj1 objectForKey:@"name"];
        else
            name1 = [obj1 objectForKey:@"personInCharge"];
        
        NSString *name2;
        if ([[obj2 objectForKey:@"Table"] isEqualToString:kUserDocType])
            name2 = [obj2 objectForKey:@"name"];
        else
            name2 = [obj2 objectForKey:@"personInCharge"];
        
        return [name1 compare:name2 options:NSCaseInsensitiveSearch];
    }];
    
    NSMutableArray *arrayResult = [NSMutableArray arrayWithCapacity:1];
    for (int i = indexFrom;i < indexFrom + count &&  i < [array count]; i++) {
        [arrayResult addObject:[array objectAtIndex:i]];
    }
    return arrayResult;
}

// Returns a filter liaison + user by type contract type in a database.
+ (NSMutableArray *) filterNewLiaisonByContactType:(NSString *) contractType from:(int)indexFrom  numberPage:(int)count {
    
    CBLView* view = [[CouchBaseLiteLib sharedCouchBaseLite].database viewNamed: @"filterNewContactByContactType"];
    if (!view.mapBlock) {
        // Register the map function, the first time we access the view:
        [view setMapBlock: MAPBLOCK({
            if ([doc[@"Table"] isEqualToString:kLiaisonDocType] && doc[@"typeLiaison"] && doc[@"personInCharge"] && ![doc[@"personInCharge"] isEqualToString:@""])
                emit(doc[@"typeLiaison"], nil);
            else if ([doc[@"Table"] isEqualToString:kUserDocType]  && [[doc objectForKey:@"status"] intValue] == 1 && doc[@"name"] && ![doc[@"name"] isEqualToString:@""])
                emit(doc[@"role"], nil);
        }) reduceBlock: nil version: @"1"]; // bump version any time you change the MAPBLOCK body!
    }
    CBLQuery *query = [view query];
    query.keys = @[contractType];
    
    NSMutableArray *array = [NSMutableArray arrayWithCapacity:1];
    for (CBLQueryRow *row in query.rows) {
        //only view by user create
        if ([[row.document propertyForKey:@"Table"] isEqualToString:kUserDocType] || ([[row.document propertyForKey:@"Table"] isEqualToString:kLiaisonDocType] && [row.document propertyForKey:@"userId"] && [[row.document propertyForKey:@"userId"] isEqualToString:[[NSUserDefaults standardUserDefaults] objectForKey:ACCOUNT_ID]])) {
            [array addObject:[row.document.properties mutableCopy]];
        }
    }
   
    [array sortUsingComparator:^(NSMutableDictionary *obj1, NSMutableDictionary *obj2){
        NSString *name1;
        if ([[obj1 objectForKey:@"Table"] isEqualToString:kUserDocType])
            name1 = [obj1 objectForKey:@"name"];
        else
            name1 = [obj1 objectForKey:@"personInCharge"];
        
        NSString *name2;
        if ([[obj2 objectForKey:@"Table"] isEqualToString:kUserDocType])
            name2 = [obj2 objectForKey:@"name"];
        else
            name2 = [obj2 objectForKey:@"personInCharge"];
        
        return [name1 compare:name2 options:NSCaseInsensitiveSearch];
    }];
    
    NSMutableArray *arrayResult = [NSMutableArray arrayWithCapacity:1];
    for (int i = indexFrom;i < indexFrom + count &&  i < [array count]; i++) {
        [arrayResult addObject:[array objectAtIndex:i]];
    }
    return arrayResult;
}

// Returns search liaison + user by key in a database.
+ (NSMutableArray *) searchNewContactByKey:(NSString *)keySearch  from:(int)indexFrom  numberPage:(int)count {
    CBLView* view = [[CouchBaseLiteLib sharedCouchBaseLite].database viewNamed: @"searchNewContact"];
    if (!view.mapBlock) {
        // Register the map function, the first time we access the view:
        [view setMapBlock: MAPBLOCK({
            if ([doc[@"Table"] isEqualToString:kLiaisonDocType] || ([doc[@"Table"] isEqualToString:kUserDocType] && [[doc objectForKey:@"status"] intValue] == 1))
                emit(doc, nil);
        }) reduceBlock: nil version: @"1"]; // bump version any time you change the MAPBLOCK body!
    }
    CBLQuery *query = [view query];
    NSMutableArray *array = [NSMutableArray arrayWithCapacity:1];
    for (CBLQueryRow *row in query.rows) {
        //only view by user create
        
        if ([[row.document.properties valueForKey:@"Table"] isEqualToString:kLiaisonDocType] && [row.document propertyForKey:@"userId"] && [[row.document propertyForKey:@"userId"] isEqualToString:[[NSUserDefaults standardUserDefaults] objectForKey:ACCOUNT_ID]]) {
            if (([row.document.properties valueForKey:@"personInCharge"] != nil && [[row.document.properties valueForKey:@"personInCharge"] rangeOfString:keySearch options:NSCaseInsensitiveSearch].location != NSNotFound)
                ||([row.document.properties valueForKey:@"email"] != nil && [[row.document.properties valueForKey:@"email"] rangeOfString:keySearch options:NSCaseInsensitiveSearch].location != NSNotFound)
                ||([row.document.properties valueForKey:@"contactNumber"] != nil && [[row.document.properties valueForKey:@"contactNumber"] rangeOfString:keySearch options:NSCaseInsensitiveSearch].location != NSNotFound)) {
                [array addObject:[row.document.properties mutableCopy]];
            }
        }
        else if ([[row.document.properties valueForKey:@"Table"] isEqualToString:kUserDocType] && [[row.document.properties valueForKey:@"status"] intValue] == 1) {
            if (([row.document.properties valueForKey:@"name"] != nil && [[row.document.properties valueForKey:@"name"] rangeOfString:keySearch options:NSCaseInsensitiveSearch].location != NSNotFound)
                ||([row.document.properties valueForKey:@"email"] != nil && [[row.document.properties valueForKey:@"email"] rangeOfString:keySearch options:NSCaseInsensitiveSearch].location != NSNotFound)
                ||([row.document.properties valueForKey:@"phone"] != nil && [[row.document.properties valueForKey:@"phone"] rangeOfString:keySearch options:NSCaseInsensitiveSearch].location != NSNotFound)) {
                [array addObject:[row.document.properties mutableCopy]];
            }
        }
    }
    
    [array sortUsingComparator:^(NSMutableDictionary *obj1, NSMutableDictionary *obj2){
        NSString *name1;
        if ([[obj1 objectForKey:@"Table"] isEqualToString:kUserDocType])
            name1 = [obj1 objectForKey:@"name"];
        else
            name1 = [obj1 objectForKey:@"personInCharge"];
        
        NSString *name2;
        if ([[obj2 objectForKey:@"Table"] isEqualToString:kUserDocType])
            name2 = [obj2 objectForKey:@"name"];
        else
            name2 = [obj2 objectForKey:@"personInCharge"];
        
        return [name1 compare:name2 options:NSCaseInsensitiveSearch];
    }];
    NSMutableArray *arrayResult = [NSMutableArray arrayWithCapacity:1];
    for (int i = indexFrom;i < indexFrom + count &&  i < [array count]; i++){
        [arrayResult addObject:[array objectAtIndex:i]];
    }
    return arrayResult;
}

+ (NSMutableArray *) queryNewLiaisonByRole:(NSString *)role from:(int)indexFrom numberPage:(int)count {
    CBLView* view = [[CouchBaseLiteLib sharedCouchBaseLite].database viewNamed: @"listsNewContact"];
    if (!view.mapBlock) {
        // Register the map function, the first time we access the view:
        [view setMapBlock: MAPBLOCK({
            if (([doc[@"Table"] isEqualToString:kLiaisonDocType] && doc[@"personInCharge"] && ![doc[@"personInCharge"] isEqualToString:@""])|| ([doc[@"Table"] isEqualToString:kUserDocType] && [[doc objectForKey:@"status"] intValue] == 1))
                emit(doc, nil);
        }) reduceBlock: nil version: @"1"]; // bump version any time you change the MAPBLOCK body!
    }
    CBLQuery *query = [view query];
    NSMutableArray *array = [NSMutableArray arrayWithCapacity:1];
    for (CBLQueryRow *row in query.rows) {
        
        //only view by user create
        if ([[row.document propertyForKey:@"Table"] isEqualToString:kLiaisonDocType] && [row.document propertyForKey:@"userId"] && [[row.document propertyForKey:@"userId"] isEqualToString:[[NSUserDefaults standardUserDefaults] objectForKey:ACCOUNT_ID]] && ![[[row.document.properties objectForKey:@"typeLiaison"] lowercaseString] isEqualToString:@"admin"]) {
            [array addObject:[row.document.properties mutableCopy]];
        }
        else if([[row.document propertyForKey:@"Table"] isEqualToString:kUserDocType]){
//            if ([role isEqualToString:@"admin"]) {
//                [array addObject:[row.document.properties mutableCopy]];
//            }
//            else
            if ([role isEqualToString:@"admin"] || [role isEqualToString:@"ma"] || [role isEqualToString:@"owner"]){
                if ([[[row.document propertyForKey:@"role"] lowercaseString] isEqualToString:@"admin"])
                    ;
                else
                    [array addObject:[row.document.properties mutableCopy]];
            }
            else if ([[[row.document propertyForKey:@"role"] lowercaseString] isEqualToString:role] && [[[row.document.properties valueForKey:@"email"] lowercaseString] isEqualToString:[[NSUserDefaults standardUserDefaults] objectForKey:USER_EMAIL]])
                [array addObject:[row.document.properties mutableCopy]];
        }
    }
    [array sortUsingComparator:^(NSMutableDictionary *obj1, NSMutableDictionary *obj2){
        NSString *name1;
        if ([[obj1 objectForKey:@"Table"] isEqualToString:kUserDocType])
            name1 = [obj1 objectForKey:@"name"];
        else
            name1 = [obj1 objectForKey:@"personInCharge"];
        
        NSString *name2;
        if ([[obj2 objectForKey:@"Table"] isEqualToString:kUserDocType])
            name2 = [obj2 objectForKey:@"name"];
        else
            name2 = [obj2 objectForKey:@"personInCharge"];
        
        return [name1 compare:name2 options:NSCaseInsensitiveSearch];
    }];
    
    NSMutableArray *arrayResult = [NSMutableArray arrayWithCapacity:1];
    for (int i = indexFrom;i < indexFrom + count &&  i < [array count]; i++) {
        [arrayResult addObject:[array objectAtIndex:i]];
    }
    return arrayResult;
}

// Returns a filter liaison + user by type contract type in a database.
+ (NSMutableArray *) filterNewLiaisonByRole:(NSString *)role byContactType:(NSString *) contractType from:(int)indexFrom  numberPage:(int)count {
    
    CBLView* view = [[CouchBaseLiteLib sharedCouchBaseLite].database viewNamed: @"filterNewContactByContactType"];
    if (!view.mapBlock) {
        // Register the map function, the first time we access the view:
        [view setMapBlock: MAPBLOCK({
            if ([doc[@"Table"] isEqualToString:kLiaisonDocType] && doc[@"typeLiaison"] && doc[@"personInCharge"] && ![doc[@"personInCharge"] isEqualToString:@""])
                emit(doc[@"typeLiaison"], nil);
            else if ([doc[@"Table"] isEqualToString:kUserDocType]  && [[doc objectForKey:@"status"] intValue] == 1 && doc[@"name"] && ![doc[@"name"] isEqualToString:@""])
                emit(doc[@"role"], nil);
        }) reduceBlock: nil version: @"1"]; // bump version any time you change the MAPBLOCK body!
    }
    CBLQuery *query = [view query];
    query.keys = @[contractType];
    
    NSMutableArray *array = [NSMutableArray arrayWithCapacity:1];
    for (CBLQueryRow *row in query.rows) {
        //only view by user create
        if ([[row.document propertyForKey:@"Table"] isEqualToString:kLiaisonDocType] && [row.document propertyForKey:@"userId"] && [[row.document propertyForKey:@"userId"] isEqualToString:[[NSUserDefaults standardUserDefaults] objectForKey:ACCOUNT_ID]] && ![[[row.document.properties objectForKey:@"typeLiaison"] lowercaseString] isEqualToString:@"admin"]) {
            [array addObject:[row.document.properties mutableCopy]];
        }
        else if([[row.document propertyForKey:@"Table"] isEqualToString:kUserDocType]){
//            if ([role isEqualToString:@"admin"]) {
//                [array addObject:[row.document.properties mutableCopy]];
//            }
            if ([role isEqualToString:@"admin"] || [role isEqualToString:@"ma"] || [role isEqualToString:@"owner"]){
                if ([[[row.document propertyForKey:@"role"] lowercaseString] isEqualToString:@"admin"])
                    ;
                else
                    [array addObject:[row.document.properties mutableCopy]];
            }
            else if ([[[row.document propertyForKey:@"role"] lowercaseString] isEqualToString:role] && [[[row.document.properties valueForKey:@"email"] lowercaseString] isEqualToString:[[NSUserDefaults standardUserDefaults] objectForKey:USER_EMAIL]])
                [array addObject:[row.document.properties mutableCopy]];
        }
    }
    
    [array sortUsingComparator:^(NSMutableDictionary *obj1, NSMutableDictionary *obj2){
        NSString *name1;
        if ([[obj1 objectForKey:@"Table"] isEqualToString:kUserDocType])
            name1 = [obj1 objectForKey:@"name"];
        else
            name1 = [obj1 objectForKey:@"personInCharge"];
        
        NSString *name2;
        if ([[obj2 objectForKey:@"Table"] isEqualToString:kUserDocType])
            name2 = [obj2 objectForKey:@"name"];
        else
            name2 = [obj2 objectForKey:@"personInCharge"];
        
        return [name1 compare:name2 options:NSCaseInsensitiveSearch];
    }];
    
    NSMutableArray *arrayResult = [NSMutableArray arrayWithCapacity:1];
    for (int i = indexFrom;i < indexFrom + count &&  i < [array count]; i++) {
        [arrayResult addObject:[array objectAtIndex:i]];
    }
    return arrayResult;
}

// Returns search liaison + user by key in a database.
+ (NSMutableArray *) searchNewContactByRole:(NSString *)role byKey:(NSString *)keySearch  from:(int)indexFrom  numberPage:(int)count {
    CBLView* view = [[CouchBaseLiteLib sharedCouchBaseLite].database viewNamed: @"searchNewContact"];
    if (!view.mapBlock) {
        // Register the map function, the first time we access the view:
        [view setMapBlock: MAPBLOCK({
            if ([doc[@"Table"] isEqualToString:kLiaisonDocType] || ([doc[@"Table"] isEqualToString:kUserDocType] && [[doc objectForKey:@"status"] intValue] == 1))
                emit(doc, nil);
        }) reduceBlock: nil version: @"1"]; // bump version any time you change the MAPBLOCK body!
    }
    CBLQuery *query = [view query];
    NSMutableArray *array = [NSMutableArray arrayWithCapacity:1];
    for (CBLQueryRow *row in query.rows) {
        //only view by user create
        
        if ([[row.document.properties valueForKey:@"Table"] isEqualToString:kLiaisonDocType] && [row.document propertyForKey:@"userId"] && [[row.document propertyForKey:@"userId"] isEqualToString:[[NSUserDefaults standardUserDefaults] objectForKey:ACCOUNT_ID]] && ![[[row.document.properties objectForKey:@"typeLiaison"] lowercaseString] isEqualToString:@"admin"]) {
            if (([row.document.properties valueForKey:@"personInCharge"] != nil && [[row.document.properties valueForKey:@"personInCharge"] rangeOfString:keySearch options:NSCaseInsensitiveSearch].location != NSNotFound)
                ||([row.document.properties valueForKey:@"email"] != nil && [[row.document.properties valueForKey:@"email"] rangeOfString:keySearch options:NSCaseInsensitiveSearch].location != NSNotFound)
                ||([row.document.properties valueForKey:@"contactNumber"] != nil && [[row.document.properties valueForKey:@"contactNumber"] rangeOfString:keySearch options:NSCaseInsensitiveSearch].location != NSNotFound)) {
                [array addObject:[row.document.properties mutableCopy]];
            }
        }
        else if ([[row.document.properties valueForKey:@"Table"] isEqualToString:kUserDocType] && [[row.document.properties valueForKey:@"status"] intValue] == 1) {
            if (([row.document.properties valueForKey:@"name"] != nil && [[row.document.properties valueForKey:@"name"] rangeOfString:keySearch options:NSCaseInsensitiveSearch].location != NSNotFound)
                ||([row.document.properties valueForKey:@"email"] != nil && [[row.document.properties valueForKey:@"email"] rangeOfString:keySearch options:NSCaseInsensitiveSearch].location != NSNotFound)
                ||([row.document.properties valueForKey:@"phone"] != nil && [[row.document.properties valueForKey:@"phone"] rangeOfString:keySearch options:NSCaseInsensitiveSearch].location != NSNotFound)) {
                
                if ([role isEqualToString:@"admin"] || [role isEqualToString:@"ma"] || [role isEqualToString:@"owner"]){
                    if ([[[row.document propertyForKey:@"role"] lowercaseString] isEqualToString:@"admin"])
                        ;
                    else
                        [array addObject:[row.document.properties mutableCopy]];
                }
                else if ([[[row.document propertyForKey:@"role"] lowercaseString] isEqualToString:role] && [[[row.document.properties valueForKey:@"email"] lowercaseString] isEqualToString:[[NSUserDefaults standardUserDefaults] objectForKey:USER_EMAIL]])
                    [array addObject:[row.document.properties mutableCopy]];
            }
        }
    }
    
    [array sortUsingComparator:^(NSMutableDictionary *obj1, NSMutableDictionary *obj2){
        NSString *name1;
        if ([[obj1 objectForKey:@"Table"] isEqualToString:kUserDocType])
            name1 = [obj1 objectForKey:@"name"];
        else
            name1 = [obj1 objectForKey:@"personInCharge"];
        
        NSString *name2;
        if ([[obj2 objectForKey:@"Table"] isEqualToString:kUserDocType])
            name2 = [obj2 objectForKey:@"name"];
        else
            name2 = [obj2 objectForKey:@"personInCharge"];
        
        return [name1 compare:name2 options:NSCaseInsensitiveSearch];
    }];
    NSMutableArray *arrayResult = [NSMutableArray arrayWithCapacity:1];
    for (int i = indexFrom;i < indexFrom + count &&  i < [array count]; i++){
        [arrayResult addObject:[array objectAtIndex:i]];
    }
    return arrayResult;
}

+ (NSMutableArray *) searchNewContactByRole:(NSString *)role byKey:(NSString *)keySearch andContactType:(NSString*)contactType from:(int)indexFrom  numberPage:(int)count {
    CBLView* view = [[CouchBaseLiteLib sharedCouchBaseLite].database viewNamed: @"filterNewContactByContactType"];
    if (!view.mapBlock) {
        // Register the map function, the first time we access the view:
        [view setMapBlock: MAPBLOCK({
            if ([doc[@"Table"] isEqualToString:kLiaisonDocType] && doc[@"typeLiaison"] && doc[@"personInCharge"] && ![doc[@"personInCharge"] isEqualToString:@""])
                emit(doc[@"typeLiaison"], nil);
            else if ([doc[@"Table"] isEqualToString:kUserDocType]  && [[doc objectForKey:@"status"] intValue] == 1 && doc[@"name"] && ![doc[@"name"] isEqualToString:@""])
                emit(doc[@"role"], nil);
        }) reduceBlock: nil version: @"1"]; // bump version any time you change the MAPBLOCK body!
    }
    CBLQuery *query = [view query];
    query.keys = @[contactType];
    
    NSMutableArray *array = [NSMutableArray arrayWithCapacity:1];
    for (CBLQueryRow *row in query.rows) {
        //only view by user create
        
        if ([[row.document.properties valueForKey:@"Table"] isEqualToString:kLiaisonDocType] && [row.document propertyForKey:@"userId"] && [[row.document propertyForKey:@"userId"] isEqualToString:[[NSUserDefaults standardUserDefaults] objectForKey:ACCOUNT_ID]] && ![[[row.document.properties objectForKey:@"typeLiaison"] lowercaseString] isEqualToString:@"admin"]) {
            if (([row.document.properties valueForKey:@"personInCharge"] != nil && [[row.document.properties valueForKey:@"personInCharge"] rangeOfString:keySearch options:NSCaseInsensitiveSearch].location != NSNotFound)
                ||([row.document.properties valueForKey:@"email"] != nil && [[row.document.properties valueForKey:@"email"] rangeOfString:keySearch options:NSCaseInsensitiveSearch].location != NSNotFound)
                ||([row.document.properties valueForKey:@"contactNumber"] != nil && [[row.document.properties valueForKey:@"contactNumber"] rangeOfString:keySearch options:NSCaseInsensitiveSearch].location != NSNotFound)) {
                [array addObject:[row.document.properties mutableCopy]];
            }
        }
        else if ([[row.document.properties valueForKey:@"Table"] isEqualToString:kUserDocType] && [[row.document.properties valueForKey:@"status"] intValue] == 1) {
            if (([row.document.properties valueForKey:@"name"] != nil && [[row.document.properties valueForKey:@"name"] rangeOfString:keySearch options:NSCaseInsensitiveSearch].location != NSNotFound)
                ||([row.document.properties valueForKey:@"email"] != nil && [[row.document.properties valueForKey:@"email"] rangeOfString:keySearch options:NSCaseInsensitiveSearch].location != NSNotFound)
                ||([row.document.properties valueForKey:@"phone"] != nil && [[row.document.properties valueForKey:@"phone"] rangeOfString:keySearch options:NSCaseInsensitiveSearch].location != NSNotFound)) {
                
                if ([role isEqualToString:@"admin"] || [role isEqualToString:@"ma"] || [role isEqualToString:@"owner"]){
                    if ([[[row.document propertyForKey:@"role"] lowercaseString] isEqualToString:@"admin"])
                        ;
                    else
                        [array addObject:[row.document.properties mutableCopy]];
                }
                else if ([[[row.document propertyForKey:@"role"] lowercaseString] isEqualToString:role] && [[[row.document.properties valueForKey:@"email"] lowercaseString] isEqualToString:[[NSUserDefaults standardUserDefaults] objectForKey:USER_EMAIL]])
                    [array addObject:[row.document.properties mutableCopy]];
            }
        }
    }
    
    [array sortUsingComparator:^(NSMutableDictionary *obj1, NSMutableDictionary *obj2){
        NSString *name1;
        if ([[obj1 objectForKey:@"Table"] isEqualToString:kUserDocType])
            name1 = [obj1 objectForKey:@"name"];
        else
            name1 = [obj1 objectForKey:@"personInCharge"];
        
        NSString *name2;
        if ([[obj2 objectForKey:@"Table"] isEqualToString:kUserDocType])
            name2 = [obj2 objectForKey:@"name"];
        else
            name2 = [obj2 objectForKey:@"personInCharge"];
        
        return [name1 compare:name2 options:NSCaseInsensitiveSearch];
    }];
    NSMutableArray *arrayResult = [NSMutableArray arrayWithCapacity:1];
    for (int i = indexFrom;i < indexFrom + count &&  i < [array count]; i++){
        [arrayResult addObject:[array objectAtIndex:i]];
    }
    return arrayResult;
}

+ (NSString *)contactIdRandom{
    int r;
    int uniqueNumber = 0;
    NSString *contactId = @"";
    while (uniqueNumber < 10) {
        r = (arc4random() % 10);
        contactId = [NSString stringWithFormat:@"%@%d",contactId,r];
        uniqueNumber++;
    }
    return contactId;
}
+ (NSDictionary *)checkContactIdGeneration:(NSString *)contactId{
    CBLView* view = [[CouchBaseLiteLib sharedCouchBaseLite].database viewNamed: @"listsLiaison"];
    if (!view.mapBlock) {
        // Register the map function, the first time we access the view:
        [view setMapBlock: MAPBLOCK({
            if ([doc[@"Table"] isEqualToString:kLiaisonDocType] && doc[@"contactId"])
                emit(doc[@"contactId"], nil);
        }) reduceBlock: nil version: @"1"]; // bump version any time you change the MAPBLOCK body!
    }
    CBLQuery *query = [view query];
    query.keys = @[contactId];
    for (CBLQueryRow *row in query.rows) {
        if ([row.document.properties valueForKey:@"personInCharge"] != nil && ![[row.document.properties valueForKey:@"personInCharge"] isEqualToString:@""]
            && [row.document.properties valueForKey:@"email"] != nil
            && ![[row.document.properties valueForKey:@"email"] isEqualToString:@""])
            return row.document.properties;
    }
    return nil;
}
+ (NSString *)generationContactId{
    NSString *contactId = @"";
    do {
        contactId = [LiaisonBaseLite contactIdRandom];
        
    } while ([LiaisonBaseLite checkContactIdGeneration:contactId] != nil);
    return contactId;
}
@end
